package 力扣算法练习.main1.part1;

import java.util.ArrayList;
import java.util.List;

public class day3 {
    /*
    将一个给定字符串 s 根据给定的行数 numRows ，以从上往下、从左到右进行 Z 字形排列。
    你的输出需要从左往右逐行读取，产生出一个新的字符串
    https://leetcode.cn/problems/zigzag-conversion/
     */
    //看了精华解后解出来的
    public String convert(String s, int numRows) {
        if (s.length()<numRows||numRows==1)return s;
        List<StringBuilder> rows=new ArrayList<>();
        //先创建numRows个StringBuilder
        for (int i = 0; i <numRows ; i++) rows.add(new StringBuilder());
        int i=0,flag=-1;//i和flag用于共同控制在z字的节点转折
        for( char c:s.toCharArray()){
            rows.get(i).append(c);
            if (i==0||i==numRows-1)flag=-flag;
            i+=flag;
        }
        StringBuilder result=new StringBuilder();
        for (StringBuilder r: rows) result.append(r);
        return result.toString();
    }


    /*
    给你一个 32 位的有符号整数 x ，返回将 x 中的数字部分反转后的结果。
    如果反转后整数超过 32 位的有符号整数的范围[−231, 231− 1] ，就返回 0。
    假设环境不允许存储 64 位整数（有符号或无符号）。
    https://leetcode.cn/problems/reverse-integer
     */
    public int reverse(int x) {
        if (x==0)return 0;
        //先统一符号然后反转最后在还原符号
        boolean flag=false;
        if (x<0){
            x=-x;
            flag=true;
        }
        int temp=0;
        while(x!=0){
            //因为int表示的数最小和最大都不会超过MIN和MAX所以要除以一个10
            if (temp<Integer.MIN_VALUE/10||temp>Integer.MAX_VALUE/10)return 0;
            temp*=10;
            temp+=x%10;
            x/=10;
        }
        if (flag)return -temp;
        return  temp;
    }




    /*
    请你来实现一个myAtoi(string s)函数，使其能将字符串转换成
    一个 32 位有符号整数（类似 C/C++ 中的 atoi 函数）。
    函数myAtoi(string s) 的算法如下：
    https://leetcode.cn/problems/string-to-integer-atoi
     */
    //虽然看上去很复杂但时间复杂度为o(n);
    public static int myAtoi(String s) {
        //将首尾的空格去除
        s=s.strip();
        boolean flag=false;//控制正负
        int t=0;
        int result=0;
        char temp;
        for (int i = 0; i < s.length(); i++) {
            temp=s.charAt(i);
            if (temp=='-'&&t==0){
                t++;
                flag=true;
                continue;
            }
            if (temp=='+'&&t==0){
                t++;
                continue;
            }
            if (temp>=48&&temp<=57){
                if(result > Integer.MAX_VALUE/10 ||result==Integer.MAX_VALUE/10&&Integer.MAX_VALUE%10<(temp-48)){
                    return Integer.MAX_VALUE;
                }
                if(result < Integer.MIN_VALUE/10 ||result==Integer.MIN_VALUE/10&&Integer.MIN_VALUE%10>-(temp-48)){
                    return Integer.MIN_VALUE;
                }
                result*=10;
                t++;//确保后面出现的负号不会影响结果
                if (flag){
                    result-=(temp-48);//为负数的情况
                }else{
                    result+=(temp-48);
                }
            }else{
                break;
            }
        }
        return result;
    }
    //官方解
    /*
    class Solution {
    public int myAtoi(String str) {
        Automaton automaton = new Automaton();
        int length = str.length();
        for (int i = 0; i < length; ++i) {
            automaton.get(str.charAt(i));
        }
        return (int) (automaton.sign * automaton.ans);
    }
}

class Automaton {
    public int sign = 1;
    public long ans = 0;
    private String state = "start";
    private Map<String, String[]> table = new HashMap<String, String[]>() {{
        put("start", new String[]{"start", "signed", "in_number", "end"});
        put("signed", new String[]{"end", "end", "in_number", "end"});
        put("in_number", new String[]{"end", "end", "in_number", "end"});
        put("end", new String[]{"end", "end", "end", "end"});
    }};

    public void get(char c) {
        state = table.get(state)[get_col(c)];
        if ("in_number".equals(state)) {
            ans = ans * 10 + c - '0';
            ans = sign == 1 ? Math.min(ans, (long) Integer.MAX_VALUE) : Math.min(ans, -(long) Integer.MIN_VALUE);
        } else if ("signed".equals(state)) {
            sign = c == '+' ? 1 : -1;
        }
    }

    private int get_col(char c) {
        if (c == ' ') {
            return 0;
        }
        if (c == '+' || c == '-') {
            return 1;
        }
        if (Character.isDigit(c)) {
            return 2;
        }
        return 3;
    }
}
     */
}
